package com.shooter.dao;

import com.shooter.note.Id;
import com.shooter.utils.Check;
import com.shooter.utils.MathUtil;
import com.shooter.utils.PrintUtil;
import com.shooter.utils.StringUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.SQLDataException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class BaseDataDb {
    private String _id_key;
    private String _id_value;
    //缓存查询key
    public static final Map<Class, ArrayList<String>> keys = new HashMap<>();

    /**
     * 格式化查询语句
     *
     * @param where
     * @param s     需要查询的值的key
     * @return
     */
    public String toSelectSql(SQLWhere where, String... s) {
        String cName = this.getClass().getSimpleName();
        String sql = "(SELECT ";
        if (s == null) {
            sql += "*";
        } else {
            for (int i = 0; i < s.length; i++) {
                if (i != 0) sql += ",";
                sql += cName + "." + s[i];
            }
        }
        sql += " FROM " + cName;
        if (where != null) sql += where.getWhere();
        sql += ")";
        return sql;
    }

    /**
     * 格式化获取SQL INSERT语句
     *
     * @return
     */
    public String toInsertSql() {
        String sql = "INSERT INTO " + this.getClass().getSimpleName();
        Map<String, String> map = getSqlKeyValue();
        String keys = "";
        String values = "";
        for (String key : map.keySet()) {
            if (_id_key != null && _id_key.equals(key)) continue;
            String ky = map.get(key);
            if (ky.equals("")) continue;
            if (keys.length() != 0) keys += ",";
            if (values.length() != 0) values += ",";
            keys += key;
            if (DBManager.isSqlWhere(ky)) {
                values += ky;
            } else {
                values += "'" + ky + "'";
            }
        }
        sql += "(" + keys + ") VALUES (" + values + ")";
        return sql;
    }

    public String toDeleteSql() {
        return toDeleteSql(null);
    }

    /**
     * 格式化获取SQL DELECT语句
     *
     * @param where 默认不填 则自动根据id去判定
     * @return
     */
    public String toDeleteSql(SQLWhere where) {
        String sql = "DELETE FROM " + this.getClass().getSimpleName();
        getSqlKeyValue();
        if (where == null || !StringUtil.checkStringNoNull(where.getWhere())) checkNoIdError();
        sql += toWhere(where);
        return sql;
    }

    public String toUpdateSql() {
        return toUpdateSql(null);
    }

    /**
     * 格式化获取SQL UPDATE语句
     *
     * @param where 默认不填 则自动根据id去判定
     * @return
     */
    public String toUpdateSql(SQLWhere where) {
        String sql = "UPDATE " + this.getClass().getSimpleName() + " SET ";
        Map<String, String> map = getSqlKeyValue();
        if (where == null || !StringUtil.checkStringNoNull(where.getWhere())) checkNoIdError();
        String setValues = "";
        for (String key : map.keySet()) {
            if (!StringUtil.checkStringNoNull(map.get(key))) continue;
            if (setValues.length() != 0) {
                setValues += ",";
            }
            setValues += "%s='%s'";
            setValues = String.format(setValues, key, map.get(key));
        }
        sql += setValues;
        sql += toWhere(where);
        return sql;
    }

    /**
     * 格式化WHERE语句
     *
     * @param where
     * @return
     */
    private String toWhere(SQLWhere where) {
        if (where == null || where.getWhere().equals("")) {
            String w = " WHERE %s='%s'";
            return String.format(w, _id_key, _id_value);
        } else {
            return where.getWhere();
        }
    }

    /**
     * 获取DATA所有 有值的 主键和值
     *
     * @return
     */
    private Map<String, String> getSqlKeyValue() {
        Map<String, String> map = new HashMap<>();
        Field[] fields = Check.getField(this.getClass());
        try {
            for (Field field : fields) {
                Id id = field.getAnnotation(Id.class);
                if (id != null) {
                    _id_key = field.getName();
                    _id_value = (String) field.get(this);
                }
                if (field.get(this) == null) continue;
                map.put(field.getName(), (String) field.get(this));
            }
        } catch (IllegalAccessException e) {
            PrintUtil.printError(e);
        }
        return map;
    }

    private Type getNoteClass(Field field) {
        return field.getAnnotatedType().getType();
    }

    //检查没有id索引的错误
    private void checkNoIdError() {
        if (_id_key == null || _id_key.equals("")) {
            try {
                throw new SQLDataException("无法找到  索引");
            } catch (SQLDataException e) {
                PrintUtil.printError(e);
            }
        }
    }

    //清理所有数据
    public void clear() {
        Field[] fields =Check.getField(this.getClass());
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            try {
                field.set(this, null);
            } catch (IllegalAccessException e) {
                PrintUtil.printError(e);
            }
        }
    }

    public ArrayList<String> getAllKey() {
        ArrayList<String> strings = getAllKey(this.getClass());
        return strings;
    }

    //获取对象中所有的变量名字
    public static ArrayList<String> getAllKey(Class aClass) {
        ArrayList<String> strings = new ArrayList<>();
        Field[] fields = Check.getField(aClass);
        for (int i = 0; i < fields.length; i++) {
            strings.add(fields[i].getName());
        }
        return strings;
    }

    public String getKeyId() {
        getSqlKeyValue();
        if (_id_key == null || _id_key.equals("")) {
            try {
                throw new Exception("没有定义主键变量.");
            } catch (Exception e) {
                PrintUtil.printError(e);
            }
        }

        return _id_key;
    }
}
